<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Range Loading Video</title>
</head>
<body>
  <video id="video" controls autoplay></video>
</body>

<script>
const video = document.getElementById("video");
let mediaSource = new MediaSource();
const videoUrl = "//obs.ispm.vip/animation-rc/916df8be0b0e650ec5aabdb440b6dc94.mp4";  // 视频文件的URL
let sourceBuffer;
let videoDuration = 0;  // 视频总时长，稍后会从服务器获取
let videoSize = 0;  // 视频文件的总大小（字节）
let bytesPerSecond = 0;  // 每秒的视频字节数
let isBuffering = false;  // 用于控制是否可以继续加载

// 设置MediaSource
video.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener("sourceopen", () => {
  console.log("MediaSource opened");
  const mimeType = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

  if (!MediaSource.isTypeSupported(mimeType)) {
    console.error("Unsupported MIME type:", mimeType);
    return;
  }

  sourceBuffer = mediaSource.addSourceBuffer(mimeType);

  // 请求视频的总时长和文件大小（可以从响应头中获取）
  fetch(videoUrl, { method: "HEAD" })
    .then((response) => {
      videoSize = parseInt(response.headers.get("Content-Length"));  // 获取文件大小
      console.log("Video size:", videoSize, "bytes");

      // 假设可以通过部分请求或者视频元数据获取到视频的总时长
      videoDuration = 195.72;  // 这里应是视频的总时长，单位为秒
      console.log("Video duration:", videoDuration, "seconds");

      // 计算每秒钟对应的字节数
      bytesPerSecond = videoSize / videoDuration;
      console.log("Bytes per second:", bytesPerSecond);
    })
    .catch((error) => console.error("Error fetching video metadata:", error));

  // 启动加载视频片段的过程
  loadNextSegment(0, 6500 * 1000); // 加载视频的前10秒

  // 视频播放时动态加载
  video.addEventListener("timeupdate", () => {
    const currentTime = video.currentTime; // 当前播放时间
    console.log("Current time:", currentTime);

    // 计算当前时间对应的字节范围
    const rangeStart = Math.floor(currentTime * bytesPerSecond);  // 按比例计算字节位置
    const rangeEnd = Math.min(rangeStart + (6500 * 1000), videoSize);  // 加载后10秒或视频结束

    // 如果当前片段还没加载，进行加载
    if (!sourceBuffer.updating && !isBuffering && (rangeEnd > sourceBuffer.buffered.end(0) || rangeStart > sourceBuffer.buffered.end(0))) {
      console.log(`Loading segment: ${rangeStart} - ${rangeEnd}`);
      loadNextSegment(rangeStart, rangeEnd);
    }
  });

  // 完成加载时通知MediaSource结束流
  sourceBuffer.addEventListener("updateend", () => {
    if (!sourceBuffer.updating && mediaSource.readyState === "open") {
      console.log("Calling endOfStream()");
      mediaSource.endOfStream();
    }
  });
});

// 通过Range请求加载视频片段
function loadNextSegment(start, end) {
  if (isBuffering) return;  // 防止在缓冲期间重复加载

  isBuffering = true;  // 开始缓冲数据
  const range = `bytes=${start}-${end - 1}`;  // 计算请求的字节范围
  console.log(`Requesting range: ${range}`);

  fetch(videoUrl, {
    headers: {
      "Range": range,
    },
  })
    .then((response) => response.arrayBuffer())
    .then((data) => {
      console.log(`Loaded segment: ${start} - ${end}`);
      sourceBuffer.appendBuffer(data);  // 将分片数据传入SourceBuffer
    })
    .catch((error) => console.error("Error loading segment:", error))
    .finally(() => {
      isBuffering = false;  // 完成缓冲，允许加载下一个分片
    });
}
</script>

</html>
